#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <string.h>

#include "htable.h"

int test_basic()
{
    htable_t* ht = htable_create(20);
    
    //add
    {
        int res = 0;
        res = htable_add(ht, "hello", -1, "world");
        assert(res == 0);
        
        res = htable_add(ht, "hello", -1, "world");
        assert(res != 0 && errno==EEXIST);
        
        res = htable_add(ht, "hello1", -1, "world1");
        assert(res == 0);
        
        res = htable_add(ht, "hello1", -1, "world1");
        assert(res != 0 && errno==EEXIST);
    }
    
    //get
    {
        char* val = 0;
        val = htable_get(ht, "hello", -1);
        assert(val && strcmp(val, "world")==0);
        
        val = htable_get(ht, "hello1", -1);
        printf("val=%s\n", val?val:"");        
        assert(val && strcmp(val, "world1")==0);
        
        val = htable_get(ht, "world", -1);
        assert(val==0);
        
    }
    
    
    //set and get
    {
        int res = 0;
        char* val = 0;
        res = htable_set(ht, "hello", -1, "world");
        assert(res == 0);
        val = htable_get(ht, "hello", -1);
        assert(val && strcmp(val, "world")==0);
        
        res = htable_set(ht, "hello", -1, "world1");
        assert(res == 0);
        val = htable_get(ht, "hello", -1);
        assert(val && strcmp(val, "world1")==0);
        
        res = htable_set(ht, "hello1", -1, "world");
        assert(res == 0);
        val = htable_get(ht, "hello1", -1);
        assert(val && strcmp(val, "world")==0);
        
        res = htable_set(ht, "hello1", -1, "world1");
        assert(res == 0);
        val = htable_get(ht, "hello1", -1);
        assert(val && strcmp(val, "world1")==0);
    }

    //rm
    {
        char* val = 0;
        val = htable_rm(ht, "hello", -1);
        assert(val && strcmp(val, "world1")==0);
        
        val = htable_rm(ht, "hello", -1);
        assert(val==0);        

        val = htable_rm(ht, "hello1", -1);
        assert(val && strcmp(val, "world1")==0);
        
        val = htable_rm(ht, "hello1", -1);
        assert(val==0);        
    }    
    
    //count
    {
        size_t count = htable_count(ht);
        assert(count == 0);
    }
    
    htable_free(ht);
    return 0;
}

static ht_action_e list_ht(void* ctx, const void* key, int ksize, void* val)
{
    printf("list: %s %s\n", key, val);
    return ht_continue;
}

int test_ext()
{
    htable_t* ht = htable_create(15);
    htable_set_plex(ht, 10);
    //expand
    {
        //htable_enable_expand(ht, 1);
        //init data
        htable_set(ht, "1", -1, "1");
        htable_set(ht, "2", -1, "2");
        htable_set(ht, "3", -1, "3");
        htable_set(ht, "4", -1, "4");
        htable_set(ht, "5", -1, "5");
        htable_set(ht, "6", -1, "6");
        htable_set(ht, "7", -1, "7");
        htable_set(ht, "8", -1, "8");
        htable_set(ht, "9", -1, "9");
        htable_set(ht, "10", -1, "10");
        htable_set(ht, "11", -1, "11");
        htable_set(ht, "12", -1, "12");
        htable_set(ht, "13", -1, "13");
        htable_set(ht, "14", -1, "14");
        htable_set(ht, "15", -1, "15");
        htable_dump(ht, stderr);
        htable_set(ht, "16", -1, "16");
        htable_dump(ht, stderr);
    }
    
    {
        char* val = 0;
        val = htable_get(ht, "1", -1);
        if (val)
            printf("get: 1-> %s\n", val);
        else
            printf("get: 1->null\n ");
        assert(val && strcmp(val, "1")==0);
    }
    
    //iter
    {
        htable_iterate(ht, list_ht, 0);
    }
    htable_clear(ht);
    htable_dump(ht, stderr);
    
    htable_free(ht);
}

int main(int argc, char* argv[])
{
    int i;
    for (i=0; i<100; i++)
    {
        printf("%d\t%d\t%d\t%d\n", i & 7, i&15, i&31, i& 63);
    }
    return 0;
    //test_basic();
    test_ext();
    return 0;
}
